home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 351-375 / 351 / pdc / pdcsrc.lzh / PDC / amiga2sun.c < prev    next >
C/C++ Source or Header  |  1990-04-06  |  9KB  |  390 lines

  1.  
  2. /*
  3.  * amiga2sun.c - Converts Metacompco format assembly to Sun format
  4.  */
  5.  
  6. #include "/usr/include/stdio.h"
  7.  
  8. #define isspace(x)  ((x) == '\n' || (x) == ' ' || (x) == '\t' || (x) == '\f')
  9.  
  10. char            argbuf[1024];
  11. char            linebuf[1024];
  12. char           *label = NULL, *opcode = NULL, *arg1 = NULL, *arg2 = NULL;
  13. int             nextlabel = 0;
  14.  
  15. struct trans {
  16.     char           *input;
  17.     char           *output;
  18. };
  19.  
  20. struct trans    table[] = {
  21.     {"DCw", ".word"},
  22.     {"DCl", ".long"},
  23.     {"DCb", ".byte"},
  24.     {"DSb", ".=.+"},
  25.     {"CODE", ".text"},
  26.     {"CNOP", ".even"},
  27.     {"EQU", "="},
  28.     {"XDEF", ".globl"},
  29.     {"STABN", ".stabn"},
  30.     {"STABS", ".stabs"},
  31.     {"END", (char *) NULL},
  32.     {"bra", "jra"},
  33.     {"move", "movl"},
  34.     {"movel", "movl"},
  35.     {"movew", "movw"},
  36.     {"moveb", "movb"},
  37.     {"add", "addl"},
  38.     {"sub", "subl"},
  39.     {"neg", "negl"},
  40.     {"asl", "asll"},
  41.     {"and", "andl"},
  42.     {(char *) NULL, (char *) NULL}
  43. };
  44.  
  45. char           *
  46. getline()
  47. {
  48.     char           *ptr;
  49.  
  50.     ptr = fgets(linebuf, 1024, stdin);
  51.     return (ptr);
  52. }
  53.  
  54. void
  55. changeopcode()
  56. {
  57.     struct trans   *start = table;
  58.     int             len;
  59.  
  60.     if (opcode != NULL) {
  61.         len = strlen(opcode) - 1;
  62.         if (len > 1 && opcode[len - 1] == '.') {
  63.             opcode[len - 1] = opcode[len];
  64.             opcode[len] = '\0';
  65.         }
  66.  
  67.         while (start->input != NULL) {
  68.             if (strcmp(opcode, start->input) == 0) {
  69.                 opcode = start->output;
  70.                 return;
  71.             }
  72.             start++;
  73.         }
  74.     }
  75. }
  76.  
  77. void
  78. changearg(arg)
  79.     char          **arg;
  80. {
  81.     char           *ptr = *arg;
  82.     int             offset, reg, reg2, num;
  83.     char            ch;
  84.  
  85.     if (ptr != NULL) {
  86.         switch (*ptr) {
  87.         case '#':
  88.             break;
  89.         case '_':
  90.             if (ptr[2] == '%')
  91.                 ptr[2] = '$';
  92.             if (strcmp(ptr, "_main") == 0) {
  93.                 *arg = "_PDC_main";
  94.                 return;
  95.             }
  96.             break;
  97.         case '(':
  98.             num = sscanf(ptr, "(A%d)%c", ®, &ch);
  99.             if (num == 1) {
  100.                 sprintf(argbuf, "a%d@", reg);
  101.                 *arg = argbuf;
  102.                 return;
  103.             }
  104.             else if (num == 2 && ch == '+') {
  105.                 sprintf(argbuf, "a%d@+", reg);
  106.                 *arg = argbuf;
  107.                 return;
  108.             }
  109.             break;
  110.         case 'A':
  111.             *ptr++ = 'a';
  112.             if (*ptr == '7')
  113.                 *arg = "sp";
  114.             return;
  115.             break;
  116.         case 'D':
  117.             *ptr++ = 'd';
  118.             return;
  119.             break;
  120.         case '0':
  121.         case '1':
  122.         case '2':
  123.         case '3':
  124.         case '4':
  125.         case '5':
  126.         case '6':
  127.         case '7':
  128.         case '8':
  129.         case '9':
  130.         case '-':
  131.             num = sscanf(ptr, "-(A%d)", ®);
  132.             if (num == 1) {
  133.                 sprintf(argbuf, "a%d@-", reg);
  134.                 *arg = argbuf;
  135.                 return;
  136.             }
  137.             num = sscanf(ptr, "%d(A%d,D%d.l)", &offset, ®, ®2);
  138.             if (num == 3) {
  139.                 sprintf(argbuf, "a%d@(%d,d%d:l)", reg, offset, reg2);
  140.                 *arg = argbuf;
  141.                 return;
  142.             }
  143.             num = sscanf(ptr, "%d(A%d,A%d.l)", &offset, ®, ®2);
  144.             if (num == 3) {
  145.                 sprintf(argbuf, "a%d@(%d,a%d:l)", reg, offset, reg2);
  146.                 *arg = argbuf;
  147.                 return;
  148.             }
  149.             num = sscanf(ptr, "%d(A%d)", &offset, ®);
  150.             if (num == 2) {
  151.                 sprintf(argbuf, "a%d@(%d)", reg, offset);
  152.                 *arg = argbuf;
  153.                 return;
  154.             }
  155.             if (strcmp("0x24,0,0,_main", ptr) == 0)
  156.                 *arg = "0x24,0,0,_PDC_main";
  157.             break;
  158.         default:
  159.             if (strcmp("\"main:F(0,1)\"", ptr) == 0)
  160.                 *arg = "\"PDC_main:F(0,1)\"";
  161.             break;
  162.         }
  163.     }
  164. }
  165.  
  166. void
  167. lex()
  168. {
  169.     char           *ptr = linebuf;
  170.     int             paren = 0;
  171.  
  172.     label = opcode = arg1 = arg2 = NULL;
  173.  
  174.     if (*ptr == ';' || *ptr == '*')
  175.         return;
  176.  
  177.     if (*ptr && !isspace(*ptr)) {
  178.         label = ptr;
  179.         while (*ptr && !isspace(*ptr))
  180.             ptr++;
  181.         *ptr++ = '\0';
  182.     }
  183.  
  184.     while (*ptr && isspace(*ptr))
  185.         ptr++;
  186.  
  187.     if (*ptr && !isspace(*ptr)) {
  188.         opcode = ptr;
  189.         while (*ptr && !isspace(*ptr))
  190.             ptr++;
  191.         *ptr++ = '\0';
  192.     }
  193.  
  194.     while (*ptr && isspace(*ptr))
  195.         ptr++;
  196.  
  197.     if (*ptr && !isspace(*ptr)) {
  198.         arg1 = ptr;
  199.         paren = 0;
  200.         while (*ptr && !isspace(*ptr) && *ptr != '\n') {
  201.             if (*ptr == '(')
  202.                 paren++;
  203.             if (*ptr == ')')
  204.                 paren--;
  205.             if (*ptr == ',' && paren == 0)
  206.                 break;
  207.             ptr++;
  208.         }
  209.         if (*ptr && *ptr == ',') {
  210.             *ptr++ = '\0';
  211.             arg2 = ptr;
  212.             while (*ptr && !isspace(*ptr) && *ptr != '\n')
  213.                 ptr++;
  214.         }
  215.         *ptr = '\0';
  216.     }
  217. }
  218.  
  219. int
  220. genmask(ptr, dir)
  221.     char           *ptr;
  222.     int             dir;
  223. {
  224.     int             reg, mask;
  225.     int             start, stop;
  226.  
  227.     mask = 0;
  228.     start = stop = -1;
  229.  
  230.     while (*ptr) {
  231.         switch (*ptr) {
  232.         case 'D':
  233.             ptr++;
  234.             stop = *ptr - '0';
  235.             if (start == -1)
  236.                 start = stop;
  237.             else {
  238.                 for (reg = start; reg <= stop; reg++)
  239.                     if (dir)
  240.                         mask |= 1 << (15 - reg);
  241.                     else
  242.                         mask |= 1 << reg;
  243.                 start = stop = -1;
  244.             }
  245.             break;
  246.         case 'A':
  247.             ptr++;
  248.             stop = *ptr - '0' + 8;
  249.             if (start == -1)
  250.                 start = stop;
  251.             else {
  252.                 for (reg = start; reg <= stop; reg++)
  253.                     if (dir)
  254.                         mask |= 1 << (15 - reg);
  255.                     else
  256.                         mask |= 1 << reg;
  257.                 start = stop = -1;
  258.             }
  259.             break;
  260.         case '-':
  261.             break;
  262.         case '/':
  263.             if (start != -1) {
  264.                 for (reg = start; reg <= stop; reg++)
  265.                     if (dir)
  266.                         mask |= 1 << (15 - reg);
  267.                     else
  268.                         mask |= 1 << reg;
  269.                 start = stop = -1;
  270.             }
  271.             break;
  272.         }
  273.         ptr++;
  274.     }
  275.     if (start != -1) {
  276.         for (reg = start; reg <= stop; reg++)
  277.             if (dir)
  278.                 mask |= 1 << (15 - reg);
  279.             else
  280.                 mask |= 1 << reg;
  281.     }
  282.     return (mask);
  283. }
  284.  
  285. void
  286. domask()
  287. {
  288.     int             mask;
  289.  
  290.     fputs(opcode, stdout);
  291.     fputs("\t", stdout);
  292.     if (*arg2 == '-') { /* Push onto Stack */
  293.         mask = genmask(arg1, 1);
  294.         sprintf(argbuf, "#%d", mask);
  295.         fputs(argbuf, stdout);
  296.         fputs(",", stdout);
  297.         changearg(&arg2);
  298.         fputs(arg2, stdout);
  299.     }
  300.     else {          /* Pull from stack */
  301.         changearg(&arg1);
  302.         fputs(arg1, stdout);
  303.         fputs(",", stdout);
  304.         mask = genmask(arg2, 0);
  305.         sprintf(argbuf, "#%d", mask);
  306.         fputs(argbuf, stdout);
  307.     }
  308. }
  309.  
  310. void
  311. putlabel(s)
  312.     char           *s;
  313. {
  314.     int             len;
  315.  
  316.     if (s != NULL) {
  317.         if (strcmp(s, "_main:") == 0)
  318.             s = "_PDC_main:";
  319.         len = strlen(s) - 1;
  320.         if (len > 2 && s[2] == '%')
  321.             s[2] = '$';
  322.         fputs(s, stdout);
  323.         if (len > 0) {
  324.             if (s[len] != ':' && (opcode == NULL || *opcode != '='))
  325.                 fputs(":", stdout);
  326.         }
  327.     }
  328. }
  329.  
  330. void
  331. translate()
  332. {
  333.     while (getline() != NULL) {
  334.         lex();
  335.         if (opcode && strcmp(opcode, "XREF") == 0)
  336.             continue;
  337.         changeopcode();
  338.         if (opcode && strcmp(opcode, "SECTION") == 0) {
  339.             if (strcmp(arg2, "CODE") == 0)
  340.                 opcode = ".text";
  341.             if (strcmp(arg2, "DATA") == 0)
  342.                 opcode = ".data";
  343.             if (strcmp(arg2, "BSS") == 0)
  344.                 opcode = ".bss";
  345.         }
  346.         if (opcode && *opcode == '=')
  347.             fputs("\t", stdout);
  348.         if (label != NULL) {
  349.             putlabel(label);
  350.         }
  351.         fputs("\t", stdout);
  352.         if (opcode != NULL) {
  353.             if (strcmp(opcode, "moveml") == 0)
  354.                 domask();
  355.             else {
  356.                 fputs(opcode, stdout);
  357.                 if (strcmp(opcode, ".data") == 0)
  358.                     arg1 = arg2 = NULL;
  359.                 if (strcmp(opcode, ".text") == 0)
  360.                     arg1 = arg2 = NULL;
  361.                 if (strcmp(opcode, ".bss") == 0)
  362.                     arg1 = arg2 = NULL;
  363.                 if (strcmp(opcode, ".even") == 0)
  364.                     arg1 = arg2 = NULL;
  365.                 if (arg1 != NULL) {
  366.                     changearg(&arg1);
  367.                     fputs("\t", stdout);
  368.                     fputs(arg1, stdout);
  369.                     if (arg2 != NULL) {
  370.                         changearg(&arg2);
  371.                         fputs(",", stdout);
  372.                         fputs(arg2, stdout);
  373.                     }
  374.                 }
  375.             }
  376.         }
  377.         fputs("\n", stdout);
  378.  
  379.     }
  380. }
  381.  
  382. void
  383. main(argc, argv)
  384.     int             argc;
  385.     char           *argv[];
  386.  
  387. {
  388.     translate();
  389. }
  390.